package com.kma.summer2012.client.view.requests;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.user.datepicker.client.DateBox;
import com.google.gwt.user.datepicker.client.DatePicker;
import com.kma.summer2012.client.constants.ConstantsHolder;
import com.kma.summer2012.client.constants.ConstantsPresenter;
import com.kma.summer2012.client.presenters.request.RequestPresenter;
import com.kma.summer2012.client.styles.style2.Recources;
import com.kma.summer2012.shared.model.UICrumbsRequest;
import com.kma.summer2012.shared.model.UICrumbsWorkItem;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class Request extends Composite implements RequestPresenter.Display {


    @UiField
    protected Label title;
    @UiField
    protected Label labelID;
    @UiField
    protected Label id;
    @UiField
    protected Label labelDate;
    @UiField
    protected Label datelbl;
    @UiField
    protected Label labelRequestInfo;
    @UiField
    protected TextArea requestInfo;
    @UiField
    protected Label labelState;
    @UiField
    protected Label state;
    @UiField
    protected Label timeRequired;
    @UiField
    protected Label labelAssignedEngineer;
    @UiField
    protected Label AssignedEngineer;
    @UiField
    protected Label labelAdditionalTools;
    @UiField
    protected VerticalPanel additionalTools;
    @UiField
    protected Label labelTimeAssigned;
    @UiField
    protected Label timeAssigned;
    @UiField
    protected SuggestBox clAddress;
    @UiField
    protected HorizontalPanel WorkField;
    @UiField
    protected HTML calendar;
    @UiField
    protected HTML dateBox;
    @UiField
    protected SuggestBox clName;
    @UiField
    protected SuggestBox clMail;
    @UiField
    protected TextArea comments;
    @UiField
    protected Label labelTypeOfWork;
    @UiField
    protected Label labelTimeRequired;
    @UiField
    protected Label labelDateAndTime;
    @UiField
    protected Label startTime;
    @UiField
    protected Label endTime;
    @UiField
    protected Label labelClName;
    @UiField
    protected Label labelClMail;
    @UiField
    protected Label labelClAddress;
    /*@UiField
    protected  Label btnCollapseExpand;*/
    @UiField
    protected Label labelComments;
    @UiField
    protected Grid comment_content;
    //Buttons
    @UiField
    protected Button saveButton;
    @UiField
    protected Button cancelButton;
    @UiField
    protected Button sendForProcessingButton;
    //@UiField
    protected Button catalog;
    @UiField
    protected Button editButtonOperator;
    @UiField
    protected Button editButtonManager;
    @UiField
    protected Button deleteCloseButton;
    @UiField
    protected Button rejectButton;
    @UiField
    protected Button backButton;
    @UiField
    protected Button closeButton;
    @UiField
    protected Button exportButton;
    @UiField
    protected Button assignButton;
    @UiField
    protected FlowPanel cField;


    //Panels
    @UiField
    VerticalPanel stTime;
    @UiField
    VerticalPanel ndTime;
    @UiField
    VerticalPanel calendarPanel;
    @UiField
    VerticalPanel workitems;
    @UiField
    VerticalPanel buttonForCatalog;


    final ListBox startTimeList = new ListBox(false);
    final ListBox endTimeList = new ListBox(false);

    protected String start_time;
    protected String end_time;


    protected DatePicker datePicker = new DatePicker();
    protected Map<Integer, UICrumbsWorkItem> workList = new HashMap<Integer, UICrumbsWorkItem>();
    protected Map<Integer, TextBox> amountOfWorkInTxtBox = new HashMap<Integer, TextBox>();
    protected Map<Integer, TextBox> amountsOfTools = new HashMap<Integer, TextBox>();
    Map<Integer, Integer> amountsOfWorkValues = new HashMap<Integer, Integer>();
    protected Map<Integer, Button> buttonsForWorkItem = new HashMap<Integer, Button>();
    protected DisclosurePanel commentField;
    final Label text = new Label();

    @Override
    public Map<Integer, Integer> getAmountsOfWorkValues() {
        return amountsOfWorkValues;
    }

    public Integer getTotalSumOfWork() {
        try {
            if (!totalSumOfWork.equals(null)) {
                return totalSumOfWork;
            } else return 0;
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    public Map<Integer, Button> getButtonsForWorkItem() {
        return buttonsForWorkItem;
    }

    public void setTotalSumOfWork(Integer totalSumOfWork) {
        this.totalSumOfWork = totalSumOfWork;
    }

    protected Integer totalSumOfWork = 0;

    HTMLPanel rootElement;
    public static ConstantsPresenter constants;
    final FlexTable flexTable;
    final VerticalPanel buttonPanel = new VerticalPanel();


    public Map<Integer, UICrumbsWorkItem> getWorkList() {
        return workList;
    }

    public void setTitle(Label title) {
        this.title = title;
    }

    public String getStartTime() {
        return start_time;
    }


    public void setStartTime(String startTime) {
        this.start_time = startTime;
    }

    public String getEndTime() {
        return end_time;
    }


    public void setEndTime(String endTime) {
        this.end_time = endTime;
    }

    public String getDateValue() {
        return text.getText();
    }

    public HTML getCalendar() {
        return calendar;
    }

    @Override
    public Integer getActualTimeOfWork() {
        try {
            try {
                return Integer.parseInt(timeRequired.getText());
            } catch (NumberFormatException e) {
                return 0;
            }
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    public HTML getDateBox() {
        return dateBox;
    }


    public HasText getState() {
        return state;
    }


    public HasText getDateOfCreation() {
        return datelbl;
    }

    public String getRequestInfo() {
        return requestInfo.getText();
    }

    public String getTextDate() {
        return this.text.getText();
    }


    public HasValue<String> getComments() {
        return comments;
    }

    public Map<Integer, TextBox> getAmountOfWorkInTxtBox() {
        /*for (Integer i: amounts.keySet()){
            try{

            } catch (NumberFormatException e){
                return
            }
        } */
        return amountOfWorkInTxtBox;
    }

    @Override
    public HasClickHandlers getSendForProcessing() {
        return sendForProcessingButton;
    }

    @Override
    public HasClickHandlers getSaveRequestButton() {
        return saveButton;
    }


    @Override
    public HasClickHandlers getOperatorEditRequestButton() {
        return editButtonOperator;
    }

    @Override
    public HasClickHandlers getManagerEditRequestButton() {
        return editButtonManager;
    }

    @Override
    public HasClickHandlers getCancelButton() {
        return cancelButton;
    }

    @Override
    public HasClickHandlers getRejectButton() {
        return rejectButton;
    }

    @Override
    public HasClickHandlers getCatalog() {
        return catalog;
    }

    @Override
    public HasClickHandlers getDeleteCloseButton() {
        return deleteCloseButton;
    }

    @Override
    public HasClickHandlers getBackButton() {
        return backButton;
    }

    @Override
    public HasClickHandlers getCloseButton() {
        return closeButton;
    }

    @Override
    public HasClickHandlers getAssignButton() {
        return assignButton;
    }

    @Override
    public HasClickHandlers getExportButton() {
        return exportButton;
    }

    @Override
    public void makeSaveButtonDisabled() {
        this.saveButton.setEnabled(false);
    }

    public void setComments(TextArea comments) {
        this.comments = comments;
    }

    public int getId() {
        return Integer.parseInt(id.getText());
    }

    public void setId(HTML id) {
        this.id = id;
    }

    public Integer getTimeRequired() {
        try {
            try {
                return Integer.parseInt(timeRequired.getText());
            } catch (NumberFormatException e) {
                return 0;
            }
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    public void setTimeRequired(String timeRequired) {
        this.timeRequired.setText("" + this.totalSumOfWork);
    }

    public HasValue<String> getClName() {
        return clName;
    }

    public void setClName(SuggestBox clName) {
        this.clName = clName;
    }

    public HasValue<String> getClMail() {
        return clMail;
    }

    public void setClMail(SuggestBox clMail) {
        this.clMail = clMail;
    }

    public HasValue<String> getClAddress() {
        return clAddress;
    }


    public void setClAddress(SuggestBox clAddress) {
        this.clAddress = clAddress;
    }


    public void setList(ArrayList<String> list) {
        list.add("  ");
        for (int i = 9; i < 19; i++) {
            String str = "" + i + ":00";
            list.add(str);
        }
    }

    private void removeRow(FlexTable flexTable, int number) {
        int numRows = flexTable.getRowCount();
        if (numRows >= 0) {

            flexTable.removeRow(number);
            updateWorkField();
        }
    }

    public void updateWorkField() {
        flexTable.setVisible(true);
        flexTable.removeAllRows();

        buttonForCatalog.add(this.catalog);

        int numRows = flexTable.getRowCount();
        int i = 0;
        for (int key : workList.keySet()) {


            flexTable.setWidget(i, 0, new Label(workList.get(key).getWorkName()));
            final int CurKey = key;
            TextBox amountTextBox = new TextBox();
            amountTextBox.addStyleName(Recources.INSTANCE.styles().input());
            if (amountsOfWorkValues.get(key) != 0) {
                amountTextBox.setValue("" + amountsOfWorkValues.get(key));
            } else
                amountsOfWorkValues.put(key, 1);


            amountTextBox.addValueChangeHandler(new ValueChangeHandler<String>() {
                public void onValueChange(ValueChangeEvent<String> event) {
                    String number = event.getValue();
                    try {
                        Integer nmb = Integer.parseInt(number);
                        if (nmb > 0) {
                            amountOfWorkInTxtBox.get(CurKey).setValue("" + nmb);
                            amountsOfWorkValues.put(CurKey, nmb);
                            timeRequired.setText("" + calculateTimeRequired());
                        } else {

                            Window.alert(constants.incorrect());
                            amountOfWorkInTxtBox.get(CurKey).setValue(constants.defaultAmountOfWork());
                            amountsOfWorkValues.put(CurKey, Integer.parseInt(constants.defaultAmountOfWork()));
                            timeRequired.setText("" + calculateTimeRequired());

                        }

                    } catch (NumberFormatException e) {
                        Window.alert("Inccorect amount ");
                    }

                }
            });

            amountOfWorkInTxtBox.put(workList.get(key).getId(), amountTextBox);


            flexTable.setWidget(i, 1, amountOfWorkInTxtBox.get(workList.get(key).getId()));
            final Button removeButton = new Button("delete");
            removeButton.addStyleName(Recources.INSTANCE.styles().Caption());
            final int id = i;                                   // number of row

            removeButton.addClickHandler(new ClickHandler() {
                public void onClick(ClickEvent event) {
                    totalSumOfWork -= amountsOfWorkValues.get(CurKey) * workList.get(CurKey).getRuntime();
                    workList.remove(CurKey);
                    amountOfWorkInTxtBox.remove(CurKey);
                    removeRow(flexTable, id);
                    timeRequired.setText("" + calculateTimeRequired());

                }
            });
            buttonsForWorkItem.put(workList.get(key).getId(), removeButton);
            flexTable.setWidget(i, 2, buttonsForWorkItem.get(workList.get(key).getId()));


            i++;
        }
        this.calculateTimeRequired();
        this.timeRequired.setText("" + this.totalSumOfWork);
    }

    public int calculateTimeRequired() {
        int result = 0;
        for (int key : workList.keySet()) {
            result += workList.get(key).getRuntime() * Integer.parseInt(amountOfWorkInTxtBox.get(key).getValue());
        }
        this.totalSumOfWork = result;
        return result;
    }

    public Request(UiBinder<HTMLPanel, Request> template) {
        constants = GWT.create(ConstantsPresenter.class);
        rootElement = template.createAndBindUi(this);
        setFieldName();


        initWidget(rootElement);

        ArrayList<String> listTypes = new ArrayList<String>();
        setList(listTypes);

        for (int i = 0; i < listTypes.size(); i++) {
            startTimeList.addItem(listTypes.get(i));
            endTimeList.addItem(listTypes.get(i));
        }


        startTimeList.addChangeHandler(new ChangeHandler() {
            public void onChange(ChangeEvent event) {
                start_time = "" + startTimeList.getItemText(startTimeList.getSelectedIndex());

            }
        });
        endTimeList.addChangeHandler(new ChangeHandler() {
            public void onChange(ChangeEvent event) {
                end_time = "" + endTimeList.getItemText(endTimeList.getSelectedIndex());
            }
        });

        stTime.setSpacing(4);
        ndTime.setSpacing(4);


        stTime.add(startTimeList);
        ndTime.add(endTimeList);


        /*
             TYPE OF WORK PANEL
        */
        flexTable = new FlexTable();
        FlexTable.FlexCellFormatter cellFormatter = flexTable.getFlexCellFormatter();


        catalog = new Button("Catalog");

        cellFormatter.setVerticalAlignment(0, 1, HasVerticalAlignment.ALIGN_TOP);

        buttonForCatalog.add(this.catalog);
        catalog.addStyleName(Recources.INSTANCE.styles().Caption3top());


        WorkField.add(flexTable);
        workitems.add(flexTable);

        /* CALENDAR   */
        datePicker.setValue(new Date(), true);

        String dateString = DateTimeFormat.getFormat(ConstantsHolder.getConstants().DATE_FORMAT_SHORT()).format(new Date());
        text.setText(dateString);

        DateTimeFormat dateFormat = DateTimeFormat.getFormat(ConstantsHolder.getConstants().DATE_FORMAT_FULL());
        DateBox dateBox = new DateBox();
        dateBox.setFormat(new DateBox.DefaultFormat(dateFormat));

        calendarPanel.add(text);
        calendarPanel.add(datePicker);


        catalog.setVisible(false);
        //visible only in edit operator mode
        deleteCloseButton.setVisible(false);
        deleteCloseButton.setVisible(false);

        closeButton.setVisible(false);
        //visible in engineer mode
        rejectButton.setVisible(false);
        backButton.setVisible(false);
        exportButton.setVisible(false);
        //visible in manager mode
        assignButton.setVisible(false);

        setStyles();
    }

    public void enableField() {

        this.clAddress.setEnabled(false);
        this.clAddress.addStyleName(Recources.INSTANCE.styles().textareaReadOnly());
        this.clAddress.setEnabled(false);
        this.clName.addStyleName(Recources.INSTANCE.styles().textareaReadOnly());
        this.clName.setEnabled(false);

        this.clMail.addStyleName(Recources.INSTANCE.styles().textareaReadOnly());
        this.clMail.setEnabled(false);
        this.comments.setEnabled(false);
        this.startTimeList.setEnabled(false);
        this.endTimeList.setEnabled(false);

        this.startTimeList.addStyleName(Recources.INSTANCE.styles().textareaReadOnly());
        this.endTimeList.addStyleName(Recources.INSTANCE.styles().textareaReadOnly());
        this.requestInfo.addStyleName(Recources.INSTANCE.styles().textareaReadOnly());
        //this.timeRequired.setEnabled(false);
        this.requestInfo.setEnabled(false);
        this.saveButton.setVisible(false);
        this.datePicker.setVisible(false);
        /*this.typeOfWork.setEnabled(false);*/

    }

    public void setStyles() {
        title.setStyleName(Recources.INSTANCE.styles().title());
        clAddress.addStyleName(Recources.INSTANCE.styles().input());
        clMail.addStyleName(Recources.INSTANCE.styles().input());
        clName.addStyleName(Recources.INSTANCE.styles().input());
        comments.addStyleName(Recources.INSTANCE.styles().input());

        requestInfo.addStyleName(Recources.INSTANCE.styles().input());
        /* rootElement.addStyleName(Recources.INSTANCE.styles().requestTable());*/
        assignButton.addStyleName(Recources.INSTANCE.styles().Caption());
        backButton.addStyleName(Recources.INSTANCE.styles().Caption());
        closeButton.addStyleName(Recources.INSTANCE.styles().Caption());
        exportButton.addStyleName(Recources.INSTANCE.styles().Caption());
        rejectButton.addStyleName(Recources.INSTANCE.styles().Caption());
        cancelButton.addStyleName(Recources.INSTANCE.styles().Caption());

        saveButton.addStyleName(Recources.INSTANCE.styles().Caption());
        editButtonOperator.addStyleName(Recources.INSTANCE.styles().Caption());
        editButtonManager.addStyleName(Recources.INSTANCE.styles().Caption());
        deleteCloseButton.addStyleName(Recources.INSTANCE.styles().Caption());
        cancelButton.addStyleName(Recources.INSTANCE.styles().Caption());
        sendForProcessingButton.addStyleName(Recources.INSTANCE.styles().Caption());
    }

    public void setFieldName() {
        this.labelID.setText(constants.id());
        this.labelDate.setText(constants.dateOfCreation());
        this.labelRequestInfo.setText(constants.requestInfo());
        this.labelState.setText(constants.stateLabel());
        this.labelTypeOfWork.setText(constants.typeOfWork());
        this.labelTimeRequired.setText(constants.timeRequired());
        this.labelDateAndTime.setText(constants.reqDate_Time());
        this.labelClName.setText(constants.clName());
        this.labelClMail.setText(constants.clEmail());
        this.labelClAddress.setText(constants.clAdd());
        this.labelComments.setText(constants.comments());

        this.saveButton.setText(constants.save());

        this.cancelButton.setText(constants.cancel());
        this.sendForProcessingButton.setText(constants.sendForProcessing());
        this.deleteCloseButton.setText(constants.delete());
        this.closeButton.setText(constants.close());
        this.assignButton.setText(constants.assign());
        this.exportButton.setText(constants.export());
        this.rejectButton.setText(constants.reject());
        this.backButton.setText(constants.back());
        this.editButtonManager.setText(constants.editRequest());
        this.editButtonOperator.setText(constants.editRequest());
        this.timeRequired.setText("");
        this.labelTimeAssigned.setText("");
        this.labelAssignedEngineer.setText("");
        this.AssignedEngineer.setText("");
    }

    @Override
    public void setParametres(UICrumbsRequest request) {
    }

    @Override
    public Widget asWidget() {
        return this;
    }


    @Override
    public Boolean validateRequestInfo() {
        if (this.id != null && !this.id.equals("") &&
                this.datelbl.getText() != null &&
                !this.datelbl.getText().equals("") &&
                !this.state.getText().equals("")) {

            try {
                for (Integer key : amountOfWorkInTxtBox.keySet()) {
                    if (amountOfWorkInTxtBox.get(key).getValue() == null ||
                            amountOfWorkInTxtBox.get(key).toString().equals("")) {

                        Window.alert("Incorrect number for amount of work");
                        return false;
                    }
                }
            } catch (Exception e) {
                return false;

            }
            try {
                int start = DateTimeFormat.getFormat("HH:mm").parse(start_time).getHours();

                //Window.alert("in presenter "+start);
                int end = DateTimeFormat.getFormat("HH:mm").parse(end_time).getHours();
                // Window.alert("in presenter " + end);
                if (start_time == null && end_time == null) {
                    Window.alert("Incorrect start and end time input  ");
                    return false;
                } else {
                    if (start > end) {
                        Window.alert("Incorrect start and end time input  ");
                        return false;

                    }


                    try {
                        Integer runTime = Integer.parseInt(timeRequired.getText());
                        if (runTime % 60 == 0) {
                            if ((runTime / 60) > (end - start)) {
                                Window.alert("Required time exceeds input start and end time");
                                return false;
                            }
                        } else if ((runTime / 60 + 1) > (end - start)) {
                            Window.alert("Required time exceeds input start and end time");
                            return false;
                        } else
                            return true;
                    } catch (Exception e) {

                    }


                }

            } catch (NullPointerException e) {
                Window.alert("Incorrect start and end time input  ");
                return false;
            }
            try {
                if (workList.size() == 0) {
                    Window.alert("Choose work");
                    return false;
                }
            } catch (NumberFormatException e) {
                Window.alert("Choose work");
                return false;
            }
        } else
            return false;
        return true;

    }

    @Override
    public Boolean validateClientInfo() {
        if (this.clAddress.getValue() == null || this.clAddress.getValue().equals("") ||
                this.clMail.getValue() == null || this.clMail.getValue().equals("") ||
                this.clName.getValue() == null || this.clName.getValue().equals("")) {

            return false;
        } else
            return this.clMail.getValue().matches("^\\S+@\\S+\\.\\S+$");

    }


}